package org.yaukie.core.impl;

import org.quartz.*;
import org.quartz.spi.JobFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaukie.core.anotation.MyJob;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @Author: yuenbin
 * @Date :2020/5/16
 * @Time :10:39
 * @Motto: It is better to be clear than to be clever !
 * @Destrib:
 **/
public abstract  class MyAbstractJob {

    private static final Logger log = LoggerFactory.getLogger(MyAbstractJob.class);

    public static final Map<Class , Scheduler> schedulerMap = new HashMap<Class , Scheduler>();


    /**
     * 启动定时器
     * @param jobClass
     * @param jobDetail
     * @param trigger
     */
    protected  void doStartJob(Class jobClass ,JobDetail jobDetail,Trigger trigger) {
        Scheduler scheduler;
        try {
            scheduler = createScheduler(jobDetail, trigger);
            scheduler.start();
            schedulerMap.put(jobClass, scheduler);
            log.debug("[MyJobInstance] started job: " + jobClass.getName());
        } catch (SchedulerException e) {
            log.error("start job "+jobClass.getSimpleName()+"  error ");
        }

    }

    /**
     * 判断该作业是否开启
     *
     * @param jobClass
     * @return
     */
    protected   boolean getJobStatus(Class jobClass) {
        boolean flag = false;
        Scheduler scheduler;
        if (schedulerMap.containsKey(jobClass)) {
            scheduler = schedulerMap.get(jobClass);
            try {
                flag = scheduler.isStarted();
                if (flag) {
                    if (log.isDebugEnabled()) {
                        log.debug("定时器" + jobClass.getSimpleName() + "已经启动,无需重复启动!");
                    }
                }

            } catch (SchedulerException e) {
                if (log.isErrorEnabled()) {
                    log.error("定时器获取启动状态异常" + e.getMessage());
                }

            }
        }
        return flag;
    }


    /**
     * 指定开始时间，结束时间 通用情况下的作业执行情况
     * @param jobClass
     * @param count
     * @param seconds
     * @param start
     * @param end
     * @return
     */
    protected  SimpleTrigger createJobSimpleTriger(Class jobClass, int count, int seconds, String start,
                                                       String end) {
        TriggerBuilder<SimpleTrigger> triggerBuilder;

        //默认使用注解指定参数
        if (jobClass.isAnnotationPresent(MyJob.class)) {
            MyJob job = (MyJob) jobClass.getAnnotation(MyJob.class);
            MyJob.JobType jobType = job.jobType();
            if (jobType.equals(MyJob.JobType.TIMER)) {
                count = job.count();
                seconds = job.seconds();
                start = job.start();
                end = job.end();
            }
        }

        if (count > 0) {
            triggerBuilder = TriggerBuilder.newTrigger()
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(count, seconds));
        } else {
            triggerBuilder = TriggerBuilder.newTrigger()
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(seconds));
        }

        return doCreateJobSimpleTrigger(triggerBuilder, start, end);

    }


    /**
     * 创建基于时间正则的触发器实例
     *
     * @param jobClass
     * @param defaultCron
     * @return
     */
    protected   Trigger createJobTrigger(Class jobClass, String defaultCron) {
        String cron = defaultCron;
        //优先使用注解指定的时间规则,否则使用默认的
        if (jobClass.isAnnotationPresent(MyJob.class)) {
             MyJob job = (MyJob) jobClass.getAnnotation(MyJob.class);
            MyJob.JobType type = job.jobType();
            if (type.equals(MyJob.JobType.CRON)) {
                cron = job.value();
            }
        }

        return TriggerBuilder.newTrigger().withIdentity(jobClass.getName())
                .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
    }


       abstract Scheduler createScheduler(JobDetail jobDetail, Trigger trigger)  throws SchedulerException;

    abstract  Scheduler getScheduler(Class jobClass) ;

    abstract SimpleTrigger doCreateJobSimpleTrigger(TriggerBuilder<SimpleTrigger> triggerBuilder, String start, String end) ;


}
